// file:arch/x86/include/arch/descript.h
// autor:jiang xinpeng
// time:2020.12.25
// copyright:(C) 2020-2050 by jiang xinpeng,All right are reserved.
#ifndef X86_DESCRIPT_H
#define X86_DESCRIPT_H

#include <lib/type.h>
#include <arch/x86.h>

// descript table sel
#define GDT_SEL 0
#define LDT_SEL 1

// descript size
#define DES_SIZE 8
// des dpl mask
#define DES_DPL_MASK(des) (((des) >> 45) & 0x3)

#pragma pack(push, 1)
typedef struct
{
    uint16_t limit_low;
    uint16_t base_low;
    uint8_t base_mid, access_right;
    uint8_t limit_high, base_high;
} des_t;
#pragma pack(pop)

static inline uint32_t _get_gdtbase()
{
    uint64_t gdtinfo;
    uint32_t base;

    StoreGDTR(gdtinfo);
    base = gdtinfo >> 16 & 0xffffffff;

    return base;
}

static inline uint32_t _get_ldtbase()
{
    uint64_t ldtinfo;
    uint32_t base;

    StoreLDTR(ldtinfo);
    base = ldtinfo >> 16 & 0xffffffff;

    return base;
}

static inline uint16_t _get_gdtlimit()
{
    uint64_t gdtinfo;
    uint16_t limit;

    StoreGDTR(gdtinfo);
    limit = gdtinfo & 0xffff;

    return limit;
}

static inline uint16_t _get_ldtlimit()
{
    uint64_t ldtinfo;
    uint16_t limit;

    StoreLDTR(ldtinfo);
    limit = ldtinfo & 0xffff;

    return limit;
}

des_t MakeDescript(uint32_t base, uint32_t limit, uint32_t attr, uint32_t type); // make descript
uint16_t AddDescript(uint64_t descript, uint8_t tal_sel);                        // add descript
int UpdateDescript(uint64_t descript, uint8_t index, uint8_t tal_sel);           // update descript
void InstallDescript(des_t descript, uint8_t index, uint8_t tal_sel);            // install descript to assign positon
void InstallDescriptTo(des_t descript, uint8_t index, uint32_t base);            // install descript to assign position

#define GetGDTbase() _get_gdtbase()      // get gdt base
#define GetLDTbase() _get_ldtbase()      // get ldt base
#define GetGDTlimit() _get_gdtlimit()    // get gdt limit
#define GetLDTlimit() _get_ldtlimit()    // get ldt limit
#define FlushTBL(vbase) X86Invlpg(vbase) // flush tbl

#endif